package com.cskaoyan.market.admin.service.impl;

import com.cskaoyan.market.admin.bo.GoodsCombineBo;
import com.cskaoyan.market.admin.bo.GoodsDetailBo;
import com.cskaoyan.market.admin.service.MarketGoodsService;
import com.cskaoyan.market.db.domain.*;
import com.cskaoyan.market.db.mapper.*;
import com.cskaoyan.market.db.vo.CatAndBrandVo;
import com.github.pagehelper.PageHelper;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import java.math.BigDecimal;
import java.time.LocalDateTime;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

/**
 * @Author：檀志浩
 * @Package：com.cskaoyan.market.service.impl
 * @Project：Project1
 * @name：MarketGoodsServiceImpl
 * @Date：2023/5/8 9:05
 * @Filename：MarketGoodsServiceImpl
 */
@Service
public class MarketGoodsServiceImpl implements MarketGoodsService {
    @Autowired
    private MarketGoodsMapper goodsMapper;
    @Autowired
    private MarketGoodsProductMapper productMapper;
    @Autowired
    private MarketGoodsAttributeMapper attributeMapper;
    @Autowired
    private MarketGoodsSpecificationMapper specificationMapper;
    @Autowired
    private MarketCategoryMapper categoryMapper;
    @Autowired
    private MarketBrandMapper brandMapper;

    @Override
    public List<MarketGoods> list(Integer page, Integer limit, String goodsSn, String sort, String order,
                                  String goodsId, String name) {
        
        
        MarketGoodsExample goodsExample = new MarketGoodsExample();
        MarketGoodsExample.Criteria criteria = goodsExample.or();
        // page limit 分页使用
        //sort order 排序使用
        // goodsSn goodsId name 条件
        if (!StringUtils.isEmpty(goodsSn)) {
            criteria.andGoodsSnEqualTo(goodsSn);
        }
        if (!StringUtils.isEmpty(goodsId)) {
            criteria.andIdEqualTo(Integer.parseInt(goodsId));
        }
        if (!StringUtils.isEmpty(name)) {
            criteria.andNameLike("%" + name + "%");
        }
        criteria.andDeletedEqualTo(false);
        goodsExample.setOrderByClause(sort + " " + order);
        PageHelper.startPage(page, limit);
        List<MarketGoods> marketGoodsList = goodsMapper.selectByExample(goodsExample);
        
        
        return marketGoodsList;
    }

    @Override
    public Map<String, Object> catAndBrand() {
        
        
        
        //品牌查询完毕
        List<MarketBrand> marketBrands = brandMapper.selectByExampleSelective(new MarketBrandExample(),
                MarketBrand.Column.id, MarketBrand.Column.name);
        //查询category
        List<MarketCategory> marketCategories = categoryMapper.selectByExampleSelective(new MarketCategoryExample(),
                MarketCategory.Column.id, MarketCategory.Column.name, MarketCategory.Column.pid);
        
        

        //进一步去组装category,将二级分类去分个类
        //下面这段代码的作用便是将分类按照pid来进行分组，将同一pid的数据放入到一个list中
        Map<Integer, List<MarketCategory>> categoriesGroupByPid = new HashMap<>();
        for (MarketCategory marketCategory : marketCategories) {
            Integer pid = marketCategory.getPid();
            List<MarketCategory> levelCategories = categoriesGroupByPid.get(pid);
            if (levelCategories == null) {
                levelCategories = new ArrayList<>();
                categoriesGroupByPid.put(pid,levelCategories);
            }
            levelCategories.add(marketCategory);
        }
        //下面这段代码将category填充准备就绪
        List<MarketCategory> l1Categories = categoriesGroupByPid.get(0);
        List<CatAndBrandVo> categoriesVOS = new ArrayList<>();
        for (MarketCategory l1Category : l1Categories) {
            CatAndBrandVo l1cavo = new CatAndBrandVo();
            l1cavo.setValue(l1Category.getId());
            l1cavo.setLabel(l1Category.getName());
            //取出其二级类目
            List<MarketCategory> l2Categories =categoriesGroupByPid.get(l1Category.getId());
            List<CatAndBrandVo> children =new ArrayList<>();
            for (MarketCategory l2Category : l2Categories) {
                CatAndBrandVo l2cavo = new CatAndBrandVo();
                l2cavo.setValue(l2Category.getId());
                l2cavo.setLabel(l2Category.getName());
                children.add(l2cavo);
            }
            l1cavo.setChildren(children);
            categoriesVOS.add(l1cavo);
        }
        //将brand准备就绪
        List<CatAndBrandVo> brandVos = new ArrayList<>();
        for (MarketBrand marketBrand : marketBrands) {
            brandVos.add(new CatAndBrandVo(marketBrand.getName(),marketBrand.getId(),null));
        }
        //将上述的两个list封装成为一个map，返回即可
        Map<String,Object> catAndBrandsVOS = new HashMap<>();
        catAndBrandsVOS.put("categoryList",categoriesVOS);
        catAndBrandsVOS.put("brandList",brandVos);
        return catAndBrandsVOS;

    }

    @Override
    public void addGoods(MarketGoods goods, List<MarketGoodsSpecification> specifications,
                         List<MarketGoodsAttribute> attributes, List<MarketGoodsProduct> products) {
        
        
        
        
        

        //首先插入goods信息
        goods.setAddTime(LocalDateTime.now());
        goods.setUpdateTime(LocalDateTime.now());
        //这个价格如何获取？
        //市场售价，counter_price不是代表最终的售卖价格，只是用来比较的一个噱头
        //零售价格，我们可以从众多的货品中取出一个最低价格来，赋值给该变量
        BigDecimal retailPrice = products.get(0).getPrice();
        for (int i = 1; i < products.size(); i++) {
            //如果出现了一个更小的价格，那么便把更小的价格赋值给retailPrice
            if(retailPrice.compareTo(products.get(i).getPrice()) == 1){
                retailPrice = products.get(i).getPrice();
            }
        }
        goods.setRetailPrice(retailPrice);
        goods.setDeleted(false);
        //执行插入操作
        try {
            goodsMapper.insert(goods);
            //如何获取goodsid？为什么呢？因为数据库插入之后，mybatis会运行一条查询语句，将获取到的id赋值给当前对象的id
            Integer id = goods.getId();

            //依次插入其他三张表数据
            for (MarketGoodsSpecification sp : specifications) {
                sp.setGoodsId(id);
                sp.setDeleted(false);
                sp.setAddTime(LocalDateTime.now());
                sp.setUpdateTime(LocalDateTime.now());
                specificationMapper.insert(sp);
            }
            //插入products表
            for (MarketGoodsProduct pd : products) {
                pd.setGoodsId(id);
                pd.setDeleted(false);
                pd.setAddTime(LocalDateTime.now());
                pd.setUpdateTime(LocalDateTime.now());
                productMapper.insert(pd);
            }
            //插入属性表
            for (MarketGoodsAttribute att : attributes) {
                att.setGoodsId(id);
                att.setDeleted(false);
                att.setAddTime(LocalDateTime.now());
                att.setUpdateTime(LocalDateTime.now());
                attributeMapper.insert(att);
            }
            
        }catch (Exception e){
            e.printStackTrace();
        }finally {
            
        }
    }

    @Override
    public int delete(MarketGoods marketGoods) {
        
        //获取mapper对象
        
        Integer id = marketGoods.getId();
        MarketGoods goods = goodsMapper.selectByPrimaryKey(id);
        if (goods==null){
            return -1;
        }
        //逻辑删除
        marketGoods.setDeleted(true);
        int i = goodsMapper.updateByPrimaryKeySelective(marketGoods);
        
        
        return i ;
    }

    @Override
    public int update(GoodsCombineBo goodsCombineBo) {

        //创建example对象
        MarketGoodsExample goodsExample = new MarketGoodsExample();
        MarketGoodsProductExample productExample = new MarketGoodsProductExample();
        MarketGoodsAttributeExample attributeExample = new MarketGoodsAttributeExample();
        MarketGoodsSpecificationExample specificationExample = new MarketGoodsSpecificationExample();
        // 从GoodsCombineBo对象获取数据
        // 获取goods
        MarketGoods goods = goodsCombineBo.getGoods();
        // 获取products
        List<MarketGoodsProduct> products = goodsCombineBo.getProducts();
        // 获取attributes
        List<MarketGoodsAttribute> attributes = goodsCombineBo.getAttributes();
        // 获取specifications
        List<MarketGoodsSpecification> specifications = goodsCombineBo.getSpecifications();
        // 修改操作，使用事务，四个表任何一个插入失败则回滚
        try {
            LocalDateTime nowTime = LocalDateTime.now();
            // 修改goods
            // 设置请求体中没有的属性
            goods.setUpdateTime(nowTime);
            goods.setDeleted(false);
            goodsExample.createCriteria().andIdEqualTo(goods.getId());
            // 执行修改
            goodsMapper.updateByPrimaryKeySelective(goods);
            // 修改attributes
            for (MarketGoodsAttribute attribute : attributes) {
                attribute.setGoodsId(goods.getId());
                // 设置请求体中没有的属性
                attribute.setUpdateTime(nowTime);
                attribute.setDeleted(false);
                // 判断是否是新增属性
                MarketGoodsAttribute exist = attributeMapper.selectByPrimaryKey(attribute.getId());
                if (exist == null) {
                    // 是新增属性，执行插入
                    attributeMapper.insertSelective(attribute);
                    continue;
                }
                // 执行修改
                attributeMapper.updateByPrimaryKeySelective(attribute);
            }
            // 修改products
            for (MarketGoodsProduct product : products) {
                // 设置请求体中没有的属性
                product.setGoodsId(goods.getId());
                product.setUpdateTime(nowTime);
                product.setDeleted(false);
                //添加条件
                productMapper.updateByPrimaryKeySelective(product);
            }
            // 插入specifications
            for (MarketGoodsSpecification specification : specifications) {
                // 设置请求体中没有的属性
                specification.setGoodsId(goods.getId());
                specification.setAddTime(nowTime);
                specification.setUpdateTime(nowTime);
                specification.setDeleted(false);
                specificationMapper.updateByPrimaryKeySelective(specification);

            }
            // 提交事务

        } catch (Exception e) {
            // 回滚事务
            return -1;
        } finally {
            // 关闭session
        }
        return 1;
    }

    @Override
    public GoodsDetailBo detail(Integer id) {
        MarketGoodsProductExample productExample = new MarketGoodsProductExample();
        MarketGoodsAttributeExample attributeExample = new MarketGoodsAttributeExample();
        MarketGoodsSpecificationExample specificationExample = new MarketGoodsSpecificationExample();
        MarketCategoryExample categoryExample = new MarketCategoryExample();
        //添加条件，查询详情
        MarketGoods goods = goodsMapper.selectByPrimaryKey(id);
        Integer goodsId = goods.getId();
        //查product表
        productExample.createCriteria().andGoodsIdEqualTo(goodsId);
        List<MarketGoodsProduct> goodsProducts = productMapper.selectByExample(productExample);
        //查 specification表
        specificationExample.createCriteria().andGoodsIdEqualTo(goodsId);
        List<MarketGoodsSpecification> goodsSpecifications = specificationMapper.selectByExample(specificationExample);
        //查attribute表
        attributeExample.createCriteria().andGoodsIdEqualTo(goodsId);
        List<MarketGoodsAttribute> goodsAttributes = attributeMapper.selectByExample(attributeExample);
        //查 category表
        MarketCategory marketCategory = categoryMapper.selectByPrimaryKey(goods.getCategoryId());

        //获取category的id和pid信息,并封装成一个对象
        ArrayList<Integer> categoryIds = new ArrayList<>();
        if (marketCategory != null) {
            categoryIds.add(marketCategory.getPid());
            categoryIds.add(marketCategory.getId());
        }
        ArrayList<Object> details = new ArrayList<>();
        //将获取的信息装在一个对象中返回
        GoodsDetailBo goodsDetailBo = new GoodsDetailBo();
        goodsDetailBo.setAttributes(goodsAttributes);
        goodsDetailBo.setCategoryIds(categoryIds);
        goodsDetailBo.setGoods(goods);
        goodsDetailBo.setProducts(goodsProducts);
        goodsDetailBo.setSpecifications(goodsSpecifications);
        return goodsDetailBo;

    }
}


